package edu.bu.cs673.superkids123.parents.view;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;

import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.AbstractNavigationView;
import edu.bu.cs673.superkids123.children.controller.AchievementController;
import edu.bu.cs673.superkids123.common.model.Achievement;
import edu.bu.cs673.superkids123.parents.controller.AchievementDetailsController;
import edu.bu.cs673.superkids123.parents.controller.ManageAchievementsController;

public class ManageAchievementsView extends AbstractNavigationView implements ListSelectionListener, ActionListener, MouseListener {

	private JPanel panel;
	private JTable achievementTable;
	private JButton addButton;
	private JButton editButton;
	private JButton deleteButton;

	private static final int[] COLUMN_WIDTHS = { 730 };
	private static final int[] ROW_HEIGHTS = { 350, 0 };

	public ManageAchievementsView(AbstractFrame mainFrame) {
		super(mainFrame);
	}

	@Override
	public String getTitle() {
		return "Achievement Manager";
	}

	@Override
	public String getBorderTitle() {
		return "Achievements";
	}

	/**
	 * @wbp.parser.entryPoint
	 */
	@Override
	protected JPanel layout() {

		panel = new JPanel();
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = COLUMN_WIDTHS;
		gbl_panel.rowHeights = ROW_HEIGHTS;
		panel.setLayout(gbl_panel);

		achievementTable = new JTable(new AchievementTableModel());
		achievementTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		achievementTable.setFillsViewportHeight(true);
		achievementTable.getTableHeader().setResizingAllowed(false);
		achievementTable.getTableHeader().setReorderingAllowed(false);
		achievementTable.getSelectionModel().addListSelectionListener(this);
		achievementTable.addMouseListener(this);
		JScrollPane achievementPane = new JScrollPane(achievementTable);
		
		GridBagConstraints achievementGBC = new GridBagConstraints();
		achievementGBC.insets = new Insets(0, 0, 5, 5);
		achievementGBC.fill = GridBagConstraints.BOTH;
		achievementGBC.gridx = 0;
		achievementGBC.gridy = 0;
		
		panel.add(achievementPane, achievementGBC);
		
		// Button Panel
		JPanel buttonPanel = new JPanel();
		GridBagConstraints gbc_buttonPanel = new GridBagConstraints();
		gbc_buttonPanel.fill = GridBagConstraints.BOTH;
		gbc_buttonPanel.gridx = 0;
		gbc_buttonPanel.gridy = 1;
		
		// Add Button
		addButton = new JButton("Add");
		addButton.addActionListener(this);
		buttonPanel.add(addButton);
		
		// Edit Button
		editButton = new JButton("Edit");
		editButton.setEnabled(false);
		editButton.addActionListener(this);
		buttonPanel.add(editButton);
		
		// Delete Button
		deleteButton = new JButton("Delete");
		deleteButton.setEnabled(false);
		deleteButton.addActionListener(this);
		buttonPanel.add(deleteButton);
		
		panel.add(buttonPanel, gbc_buttonPanel);

		return panel;
	}

	public class AchievementTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 1L;
		private String[] columns = { "Name", "Description", "Prize", "Points" };
		private List<Achievement> achievements = getMainFrame()
				.getController(AchievementController.class).getAllActiveAchievements();

		public Achievement getAchievement(int index) {
			return achievements.get(index);
		}
		
		public void updateModel() {
			achievements = getMainFrame()
				.getController(AchievementController.class)
				.getAllActiveAchievements();
		}

		@Override
		public String getColumnName(int col) {
			return columns[col];
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			Achievement achievement = achievements.get(rowIndex);
			switch (columnIndex) {
			case 0:
				return achievement.getName();
			case 1:
				return achievement.getDescription();
			case 2:
				return achievement.getPrize();
			case 3:
				return achievement.getPoints();
			}
			return "";
		}

		@Override
		public int getRowCount() {
			return achievements.size();
		}

		@Override
		public int getColumnCount() {
			return columns.length;
		}
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		
		// No Rows Selected
		if (!e.getValueIsAdjusting() && achievementTable.getSelectedRowCount() == 0) {
			editButton.setEnabled(false);
			deleteButton.setEnabled(false);
		} 
		// Only 1 row selected
		else if (!e.getValueIsAdjusting() && achievementTable.getSelectedRowCount() == 1) {
			editButton.setEnabled(true);
			deleteButton.setEnabled(true);
		} 
		// More then 1 row selected
		else if (!e.getValueIsAdjusting() && achievementTable.getSelectedRowCount() > 1) {
			editButton.setEnabled(false);
			deleteButton.setEnabled(true);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		
		if (e.getSource() instanceof JButton) {
			if (e.getSource() == addButton) {
				getMainFrame().getController(AchievementDetailsController.class).addAchievement();
			} 
			else if (e.getSource() == editButton) {
				this.editSelectedAchievement();
			}
			else if (e.getSource() == deleteButton) {
				int[] selectedIndexes = achievementTable.getSelectedRows();
				
				int result = JOptionPane.showConfirmDialog(null, 
						"Are you sure you want to delete the selected Achievement(s)?", 
						"Delete Achievement(s)?", 
						JOptionPane.YES_NO_OPTION);
		
				if (result == JOptionPane.YES_OPTION) {
					ArrayList<Achievement> achievementsToDelete = new ArrayList<Achievement>();
					for (int index : selectedIndexes) {
						achievementsToDelete.add(((AchievementTableModel) achievementTable.getModel())
								.getAchievement(index));						
					}
					
					for (Achievement achievement : achievementsToDelete) {
						getMainFrame().getController(ManageAchievementsController.class).disableAchievement(achievement);
					}
					
					((AchievementTableModel) achievementTable.getModel()).updateModel();
					((AchievementTableModel) achievementTable.getModel()).fireTableDataChanged();
				}
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getClickCount() == 2)
			this.editSelectedAchievement();
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	// Private Interface
	
	private void editSelectedAchievement() {
		int selectedIndex = achievementTable.getSelectedRow();
		
		if (selectedIndex >= 0) {
			Achievement achievement = ((AchievementTableModel) achievementTable.getModel())
					.getAchievement(selectedIndex);
			getMainFrame().getController(AchievementDetailsController.class).editAchievement(achievement);
		}
	}
}
